package com.pai4j.connect.messagequeue.config;

import com.pai4j.common.enums.messagequeue.MessageBroadChannelEnum;
import com.pai4j.connect.messagequeue.consumer.redis.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.ErrorHandler;
import lombok.extern.slf4j.Slf4j;

@Configuration
@Slf4j
public class RedisConfig {


    /**
     * 配置RedisTemplate Bean
     *
     * @param redisConnectionFactory Redis连接工厂
     * @return RedisTemplate<String, Object>
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        
        // 设置key序列化方式string
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // 设置value的序列化方式json
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        
        // 设置hash key 和value序列化模式
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        
        // 默认的序列化器
        redisTemplate.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
        
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    @Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory redisConnectionFactory,
                                                 ChatNotifyRedisQueueListener notifyQueueListener,
                                                 ArticlePushRedisQueueListener articlePushRedisQueueListener,
                                                 InteractionNotificationRedisQueueListener interactionNotificationRedisQueueListener,
                                                 ChatMessageRedisQueueListener chatMessageRedisQueueListener,
                                                 WebRtcSDPRedisQueueListener webRtcSDPRedisQueueListener,
                                                 GroupVideoCallRedisQueueListener groupVideoCallRedisQueueListener,
                                                 GroupVideoUserChangeRedisQueueListener groupVideoUserChangeRedisQueueListener) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        // 设置链接工厂
        container.setConnectionFactory(redisConnectionFactory);
        // 统一异常处理，避免未设置ErrorHandler导致的警告并增强可观测性
        container.setErrorHandler(new ErrorHandler() {
            @Override
            public void handleError(Throwable t) {
                log.warn("RedisMessageListenerContainer encountered listener error: {}", t.getMessage(), t);
            }
        });
        // 配置消息监听器
        container.addMessageListener(interactionNotificationRedisQueueListener, new ChannelTopic(MessageBroadChannelEnum.QUEUE_INTERACTION_NOTIFY.getChannel()));
        container.addMessageListener(notifyQueueListener, new ChannelTopic(MessageBroadChannelEnum.QUEUE_CHAT_NOTIFY.getChannel()));
        container.addMessageListener(articlePushRedisQueueListener, new ChannelTopic(MessageBroadChannelEnum.QUEUE_ARTICLE_PUSH_MESSAGE.getChannel()));
        container.addMessageListener(chatMessageRedisQueueListener, new ChannelTopic(MessageBroadChannelEnum.QUEUE_CHAT_MESSAGE.getChannel()));
        container.addMessageListener(webRtcSDPRedisQueueListener, new ChannelTopic(MessageBroadChannelEnum.QUEUE_VIDEO_SDP.getChannel()));
        container.addMessageListener(groupVideoCallRedisQueueListener, new ChannelTopic(MessageBroadChannelEnum.QUEUE_GROUP_VIDEO_CALL.getChannel()));
        container.addMessageListener(groupVideoUserChangeRedisQueueListener, new ChannelTopic(MessageBroadChannelEnum.QUEUE_GROUP_VIDEO_USER_CHANGE.getChannel()));
        return container;
    }
}
